package cn.fufeiii.bt.bitcalc;

import cn.hutool.core.util.StrUtil;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author FuFei
 */
public class BitCalcMain {


    public static void main(String[] args) {
        // 保存联系组 将多个属性进行计算后存入数据库
        List<ContactTypeEnum> list = List.of(ContactTypeEnum.SMS, ContactTypeEnum.EMAIL);
        Integer calculate = calculate(list);
        System.out.println("保存时的 枚举 转换 组合数");
        System.out.println(prettyBinary(Integer.toBinaryString(calculate)));

        // 查询满足这一种方式的联系组
        System.out.println("查询时的转换 枚举 转换 组合数");
        List<Integer> transformList = transformToCombo(ContactTypeEnum.SMS);
        System.out.println(transformList.stream().map(Integer::toBinaryString).map(BitCalcMain::prettyBinary).collect(Collectors.toList()));

        // 查询满足这种方式的联系组
        Set<Integer> transformSet = new HashSet<>(transformToCombo(ContactTypeEnum.SMS));
        transformSet.addAll(transformToCombo(ContactTypeEnum.EMAIL));
        System.out.println(transformSet.stream().map(Integer::toBinaryString).map(BitCalcMain::prettyBinary).collect(Collectors.toList()));

        // 将查出来的组合数 转为 对应的枚举
        System.out.println("查询时的转换 组合数 转换 枚举");
        System.out.println(transformToEnum(calculate(list)));

    }

    public static Integer calculate(List<ContactTypeEnum> contactTypeEnumList) {
        Integer comboContactTypeCode = 0;
        for (ContactTypeEnum contactTypeEnum : contactTypeEnumList) {
            comboContactTypeCode |= contactTypeEnum.getCode();
        }
        return comboContactTypeCode;
    }

    private static String prettyBinary(String binary) {
        return StrUtil.fillBefore(binary, '0', Integer.toBinaryString(ContactTypeEnum.FULL_TYPE).length());
    }

    public static List<Integer> transformToCombo(ContactTypeEnum contactTypeEnum) {
        List<Integer> comboContactTypeCodeList = new ArrayList<>();
        for (Integer i = 1; i <= ContactTypeEnum.FULL_TYPE; i++) {
            Integer code = contactTypeEnum.getCode();
            if ((i & code) == code) {
                comboContactTypeCodeList.add(i);
            }
        }
        return comboContactTypeCodeList;
    }

    public static List<ContactTypeEnum> transformToEnum(Integer comboContactTypeCode) {
        List<ContactTypeEnum> comboContactTypeCodeList = new ArrayList<>();
        for (ContactTypeEnum contactTypeEnum : ContactTypeEnum.values()) {
            Integer code = contactTypeEnum.getCode();
            if ((code & comboContactTypeCode) == code) {
                comboContactTypeCodeList.add(contactTypeEnum);
            }
        }
        return comboContactTypeCodeList;
    }

}